#include <avr/io.h>
#include <avr/interrupt.h>

#include "spi.h"

/** SPI configuration **/
#define SPI_MASTER      ENABLE
#define SPI_INTERRUPT   ENABLE

#define SPI_DATA_ORDER  DISABLE         // DISABLE = MSB sent first, 
                                        // ENABLE = LSB sent first

#define SPI_DATA_MODES  0               //0-3 data modes see datasheeth p. 139      

#define SPI_CLOCK_RATE_SELECT FREQ_DIV_4    // See "SCK relation with oscillator frequency" above

#define DELAY_SPI   255

/* SPI Interface configuration */
#define PORT_SPI    PORTB
#define CONFPORT_SPI    DDRB

unsigned char volatile spi_transfor_complete = TRUE;

void init_SPI(void)
{    
    #if (SPI_MASTER == DISABLE)
        CONFPORT_SPI = 0b01000000; 
    #else   
        CONFPORT_SPI = 0b10110000;
    #endif
                      
    SPCR =  (SPI_INTERRUPT<<7) | (0x40) | (SPI_DATA_ORDER<<5) | (SPI_MASTER<<4) | (SPI_DATA_MODES<<2) | (SPI_CLOCK_RATE_SELECT&0x03);
	SPSR |=  (SPI_CLOCK_RATE_SELECT>>2);  
    spi_transfor_complete = TRUE;  

	asm volatile("in r30,0x0E");
	asm volatile("in r30,0x0F");       
    
      // sclk, MOSI, SS = output
     DDRB |= 0b10110000; 

    #if (SPI_INTERRUPT == ENABLE)
 	   asm("sei");  
    #endif  
}

void SPI_transmit(char cData)
{
    char unsigned count_max = DELAY_SPI;
    
    SPDR = cData;
    spi_transfor_complete = FALSE;

    #if (SPI_INTERRUPT == ENABLE)
    while((!spi_transfor_complete) && (count_max))
	{
        count_max--;
    }
    #else    
	while((!(SPSR & (1<<SPSR.7))) && (count_max))
	{
        count_max--;
    }
    #endif
}

unsigned char SPI_read()
{
    // Send "dummy byte" (to generate 8 clock periods)
    SPI_transmit(0);      
    return SPDR;
}

ISR(SPI_STC_vect)
{
    spi_transfor_complete = TRUE;
}
